home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / vbasic / setup1.exe / SETUP1.BAS < prev    next >
BASIC Source File  |  1993-07-09  |  27KB  |  787 lines

  1. Dim gGroupName As String    ' Contains the ProgMan group name for the application
  2.  
  3. Sub AddShareIfNeeded (SharePath$, ShareFile$)
  4.     On Error GoTo ShareError
  5.  
  6.     fh% = FreeFile
  7.     Open "C:\AUTOEXEC.BAT" For Input As fh%
  8.  
  9.     fFound% = 0
  10.     While Not fFound% And Not EOF(fh%)
  11.     Line Input #fh%, Temp1$
  12.     If InStr(1, UCase$(Temp1$), "REM") = 0 And InStr(1, Temp1$, ";") = 0 And InStr(1, UCase$(Temp1$), "SHARE") > 0 Then
  13.        fFound% = True
  14.     End If
  15.     Wend
  16.  
  17.     Close #fh%
  18.  
  19.     If Not fFound% Then
  20.     MsgBox "Please add <PATH>SHARE.EXE /L:500 to your AUTOEXEC.BAT"
  21.     End If
  22.  
  23.     Exit Sub
  24. ShareError:
  25.     Close #fh%, #fh2%
  26.     Exit Sub
  27. End Sub
  28.  
  29. '-------------------------------------------------------
  30. ' Centers the passed form just above center on the screen
  31. '-------------------------------------------------------
  32. Sub CenterForm (x As Form)
  33.   
  34.     Screen.MousePointer = 11
  35.     x.Top = (Screen.Height * .85) / 2 - x.Height / 2
  36.     x.Left = Screen.Width / 2 - x.Width / 2
  37.     Screen.MousePointer = 0
  38.  
  39. End Sub
  40.  
  41. Sub ConcatSplitFiles (firstfile$, cSplit%)
  42.     Dim x%, fh1%, fh2%, outfile$, outfileLen&, CopyLeftOver&, CopyChunk#, filevar$
  43.     Dim iFileMax%, iFile%, y%
  44.  
  45.     For x% = 2 To cSplit%
  46.     
  47.     fh1% = FreeFile
  48.     Open Left$(firstfile$, Len(firstfile$) - 1) + Format$(1) For Binary As fh1%
  49.         
  50.     fh2% = FreeFile
  51.     outfile$ = Left$(firstfile$, Len(firstfile$) - 1) + Format$(x%)
  52.     Open outfile$ For Binary As fh2%
  53.         
  54.     ' Goto the end of file (plus one bytes) to start writing data
  55.     Seek #fh1%, LOF(fh1%) + 1
  56.  
  57.     outfileLen& = LOF(fh2%)
  58.     CopyLeftOver& = outfileLen& Mod 10
  59.     CopyChunk# = (outfileLen& - CopyLeftOver&) / 10
  60.     filevar$ = String$(CopyLeftOver&, 32)
  61.     Get #fh2%, , filevar$
  62.     Put #fh1%, , filevar$
  63.     filevar$ = String$(CopyChunk#, 32)
  64.     iFileMax% = 10
  65.     For iFile% = 1 To iFileMax%
  66.         Get #fh2%, , filevar$
  67.         Put #fh1%, , filevar$
  68.     Next iFile%
  69.  
  70.     Close fh1%, fh2%
  71.     y% = SetTime(outfile$, firstfile$)
  72.     Kill outfile$
  73.  
  74.     Next x%
  75.     
  76.     FileCopy Left$(firstfile$, Len(firstfile$) - 1) + Format$(1), firstfile$
  77.     Kill Left$(firstfile$, Len(firstfile$) - 1) + Format$(1)
  78. End Sub
  79.  
  80. '---------------------------------------------------------------
  81. ' Copies file SrcFilename from SourcePath to DestinationPath.
  82. '
  83. ' Returns 0 if it could not find the file, or other runtime
  84. ' error occurs.  Otherwise, returns true.
  85. '
  86. ' If the source file is older, the function returns success (-1)
  87. ' even though no file was copied, since no error occurred.
  88. '---------------------------------------------------------------
  89. Function CopyFile (ByVal SourcePath As String, ByVal DestinationPath As String, ByVal SrcFilename As String, ByVal DestFileName As String)
  90. ' ----- VerInstallFile() flags -----
  91.     Const VIFF_FORCEINSTALL% = &H1, VIFF_DONTDELETEOLD% = &H2
  92.     Const OF_DELETE% = &H200
  93.     Const VIF_TEMPFILE& = &H1
  94.     Const VIF_MISMATCH& = &H2
  95.     Const VIF_SRCOLD& = &H4
  96.  
  97.     Const VIF_DIFFLANG& = &H8
  98.     Const VIF_DIFFCODEPG& = &H10
  99.     Const VIF_DIFFTYPE& = &H20
  100.     Const VIF_WRITEPROT& = &H40
  101.     Const VIF_FILEINUSE& = &H80
  102.     Const VIF_OUTOFSPACE& = &H100
  103.     Const VIF_ACCESSVIOLATION& = &H200
  104.     Const VIF_SHARINGVIOLATION = &H400
  105.     Const VIF_CANNOTCREATE = &H800
  106.     Const VIF_CANNOTDELETE = &H1000
  107.     Const VIF_CANNOTRENAME = &H2000
  108.     Const VIF_CANNOTDELETECUR = &H4000
  109.     Const VIF_OUTOFMEMORY = &H8000
  110.  
  111.     Const VIF_CANNOTREADSRC = &H10000
  112.     Const VIF_CANNOTREADDST = &H20000
  113.  
  114.     Const VIF_BUFFTOOSMALL = &H40000
  115.     Dim TmpOFStruct As OFStruct
  116.     On Error GoTo ErrorCopy
  117.  
  118.     Screen.MousePointer = 11
  119.  
  120.     '--------------------------------------
  121.     ' Add ending \ symbols to path variables
  122.     '--------------------------------------
  123.     If Right$(SourcePath$, 1) <> "\" Then
  124.     SourcePath$ = SourcePath$ + "\"
  125.     End If
  126.     If Right$(DestinationPath$, 1) <> "\" Then
  127.     DestinationPath$ = DestinationPath$ + "\"
  128.     End If
  129.     
  130.     '----------------------------
  131.     ' Update status dialog info
  132.     '----------------------------
  133.     Statusdlg.Label1.Caption = "Source file: " + Chr$(10) + Chr$(13) + UCase$(SourcePath$ + SrcFilename$)
  134.     Statusdlg.Label1.Refresh
  135.     Statusdlg.Label2.Caption = "Destination file: " + Chr$(10) + Chr$(13) + UCase$(DestinationPath$ + DestFileName$)
  136.     Statusdlg.Label2.Refresh
  137.  
  138.     '-----------------------------------------
  139.     ' Check the validity of the path and file
  140.     '-----------------------------------------
  141. CheckForExist:
  142.     If Not FileExists(SourcePath$ + SrcFilename$) Then
  143.     Screen.MousePointer = 0
  144.     x% = MsgBox("Error occurred while attempting to copy file.  Could not locate file: """ + SourcePath$ + SrcFilename$ + """", 34, "SETUP")
  145.     Screen.MousePointer = 11
  146.     If x% = 3 Then
  147.         CopyFile = False
  148.     ElseIf x% = 4 Then
  149.         GoTo CheckForExist
  150.     ElseIf x% = 5 Then
  151.         GoTo SkipThisFile
  152.     End If
  153.     Else
  154.     '-------------------------------------------------
  155.     ' VerInstallFile installs the file. We need to initialize
  156.     ' some arguments for the temp file that is created by the call
  157.     '-------------------------------------------------
  158. TryToCopyAgain:
  159.     CurrDir$ = String$(255, 0)
  160.     TmpFile$ = String$(255, 0)
  161.     lpwTempFileLen% = 255
  162.     InFileVer$ = GetFileVersion(SourcePath$ + SrcFilename$)
  163.     OutFileVer$ = GetFileVersion(DestinationPath$ + DestFileName$)
  164.     
  165.     ' Install if no version info is available
  166.     If Len(InFileVer$) <> 0 And Len(OutFileVer$) <> 0 Then
  167.         ' Don't install older or same version of file
  168.         If InFileVer$ <= OutFileVer$ Then
  169.         UpdateStatus GetFileSize(SourcePath$ + SrcFilename$)
  170.         CopyFile = True
  171.         Exit Function
  172.         End If
  173.     End If
  174.  
  175.     Result& = VerInstallFile&(0, SrcFilename$, DestFileName$, SourcePath$, DestinationPath$, CurrDir$, TmpFile$, lpwTempFileLen%)
  176.  
  177.     '--------------------------------------------
  178.     ' After copying, update the installation meter
  179.     '---------------------------------------------
  180.     
  181.     S$ = DestinationPath$
  182.     If Right$(S$, 1) <> "\" Then S$ = S$ + "\"
  183.     S$ = S$ + DestFileName$
  184.     If Not TryAgain% Then UpdateStatus GetFileSize(S$)
  185.  
  186.     '--------------------------------
  187.     ' There are many return values that you can test for.
  188.     ' The constants are listed above.
  189.     ' The following lines of code return will set the Function to
  190.     ' True if the VerInstallFile call was successful.
  191.     '
  192.     ' If the call was unsuccessful due to a different language on the
  193.     ' users machine, VerInstallFile is called again to force installation.
  194.     ' You can change this to not install if you choose.
  195.     ' Be careful about using FORCEINSTALL.  Other flags could be
  196.     ' set which indicate that this file should not be overridden.
  197.     '
  198.     ' Under any other circumstance, the tempfile created by VerInstallFile
  199.     ' is removed using OpenFile and the CopyFile function returns false.
  200.     '--------------------------------------------------------
  201.     
  202.     If Result& = 0 Or (Result& And VIF_SRCOLD&) = VIF_SRCOLD& Then
  203.         CopyFile = True
  204.     ElseIf (Result& And VIF_DIFFLANG&) = VIF_DIFFLANG& Then
  205.         Result& = VerInstallFile&(VIFF_FORCEINSTALL%, SrcFilename$, DestFileName$, SourcePath$, DestinationPath$, CurrDir$, TmpFile$, lpwTempFileLen%)
  206.         CopyFile = True
  207.     ElseIf (Result& And VIF_DIFFTYPE&) = VIF_DIFFTYPE& Then
  208.         'Fixes problem where the 3.0 version of THREED does not overwrite the 2.0 version
  209.         'Will fix any other problem where a file doesn't install because the type changed from one version to the next
  210.         Result& = VerInstallFile&(VIFF_FORCEINSTALL%, SrcFilename$, DestFileName$, SourcePath$, DestinationPath$, CurrDir$, TmpFile$, lpwTempFileLen%)
  211.         CopyFile = True
  212.     ElseIf (Result& And VIF_WRITEPROT&) = VIF_WRITEPROT& Then
  213.         Result& = VerInstallFile&(VIFF_FORCEINSTALL%, SrcFilename$, DestFileName$, SourcePath$, winSysDir$ + "\", CurrDir$, TmpFile$, lpwTempFileLen%)
  214.         CopyFile = True
  215.     ElseIf (Result& And VIF_CANNOTREADSRC) = VIF_CANNOTREADSRC Then
  216.         ' VerInstallFile does will not handle compressed files that have been split.
  217.         ' Use VB's FileCopy stmt
  218.         FileCopy SourcePath$ + SrcFilename$, DestinationPath$ + DestFileName$
  219.         CopyFile = True
  220.     Else
  221.         Screen.MousePointer = 0
  222.         If (Result& And VIF_FILEINUSE&) = VIF_FILEINUSE& Then
  223.         x% = MsgBox(DestFileName$ & " is in use. Please close all applications and re-attempt Setup.", 34)
  224.         If x% = 3 Then
  225.             CopyFile = False
  226.         ElseIf x% = 4 Then
  227.             TryAgain% = True
  228.             GoTo TryToCopyAgain
  229.         ElseIf x% = 5 Then
  230.             CopyFile = True
  231.             GoTo SkipThisFile
  232.         End If
  233.         Else
  234.         MsgBox DestFileName$ & " could not be installed."
  235.         CopyFile = False
  236.         End If
  237.         Screen.MousePointer = 11
  238.     End If
  239.  
  240.     If (Result& And VIF_TEMPFILE&) = VIF_TEMPFILE& Then copyresult% = OpenFile(TmpFile$, TmpOFStruct, OF_DELETE%)
  241.        Screen.MousePointer = 0
  242.        Exit Function
  243.     End If
  244.  
  245. SkipThisFile:
  246.        Exit Function
  247. ErrorCopy:
  248.     CopyFile = False
  249.     Screen.MousePointer = 0
  250.     Exit Function
  251.  
  252. End Function
  253.  
  254. '---------------------------------------------
  255. ' Create the path contained in DestPath$
  256. ' First char must be drive letter, followed by
  257. ' a ":\" followed by the path, if any.
  258. '---------------------------------------------
  259. Function CreatePath (ByVal DestPath$) As Integer
  260.     Screen.MousePointer = 11
  261.  
  262.     '---------------------------------------------
  263.     ' Add slash to end of path if not there already
  264.     '---------------------------------------------
  265.     If Right$(DestPath$, 1) <> "\" Then
  266.     DestPath$ = DestPath$ + "\"
  267.     End If
  268.       
  269.  
  270.     '-----------------------------------
  271.     ' Change to the root dir of the drive
  272.     '-----------------------------------
  273.     On Error Resume Next
  274.     ChDrive DestPath$
  275.     If Err <> 0 Then GoTo errorOut
  276.     ChDir "\"
  277.  
  278.     '-------------------------------------------------
  279.     ' Attempt to make each directory, then change to it
  280.     '-------------------------------------------------
  281.     BackPos = 3
  282.     forePos = InStr(4, DestPath$, "\")
  283.     Do While forePos <> 0
  284.     temp$ = Mid$(DestPath$, BackPos + 1, forePos - BackPos - 1)
  285.  
  286.     Err = 0
  287.     MkDir temp$
  288.     If Err <> 0 And Err <> 75 Then GoTo errorOut
  289.  
  290.     Err = 0
  291.     ChDir temp$
  292.     If Err <> 0 Then GoTo errorOut
  293.  
  294.     BackPos = forePos
  295.     forePos = InStr(BackPos + 1, DestPath$, "\")
  296.     Loop
  297.          
  298.     CreatePath = True
  299.     Screen.MousePointer = 0
  300.     Exit Function
  301.          
  302. errorOut:
  303.     MsgBox "Error While Attempting to Create Directories on Destination Drive.", 48, "SETUP"
  304.     CreatePath = False
  305.     Screen.MousePointer = 0
  306.  
  307. End Function
  308.  
  309. '-------------------------------------------------------------
  310. ' Procedure: CreateProgManGroup
  311. ' Arguments: X           The Form where a Label1 exist
  312. '            GroupName$  A string that contains the group name
  313. '            GroupPath$  A string that contains the group file
  314. '                        name  ie 'myapp.grp'
  315. '-------------------------------------------------------------
  316. Sub CreateProgManGroup (x As Form, groupname$, GroupPath$)
  317.     
  318.     Screen.MousePointer = 11
  319.     
  320.     '----------------------------------------------------------------------
  321.     ' Windows requires DDE in order to create a program group and item.
  322.     ' Here, a Visual Basic label control is used to generate the DDE messages
  323.     '----------------------------------------------------------------------
  324.     On Error Resume Next
  325.  
  326.     
  327.     '--------------------------------
  328.     ' Set LinkTopic to PROGRAM MANAGER
  329.     '--------------------------------
  330.     x.Label1.LinkTopic = "ProgMan|Progman"
  331.     x.Label1.LinkMode = 2
  332.     For i% = 1 To 10                                         ' Loop to ensure that there is enough time to
  333.       z% = DoEvents()                                        ' process DDE Execute.  This is redundant but needed
  334.     Next                                                     ' for debug windows.
  335.     x.Label1.LinkTimeout = 100
  336.  
  337.     '---------------------
  338.     ' Create program group
  339.     '---------------------
  340.     x.Label1.LinkExecute "[CreateGroup(" + groupname$ + Chr$(44) + GroupPath$ + ")]"
  341.  
  342.     'This is needed to fix a problem where CreateProgManItem does
  343.     'not take a parameter for groupname, but needs to know the group name
  344.     'The following assumes that this function will be called before CreateProgManItem
  345.     gGroupName = groupname
  346.  
  347.     '-----------------
  348.     ' Reset properties
  349.     '-----------------
  350.     x.Label1.LinkTimeout = 50
  351.     x.Label1.LinkMode = 0
  352.     
  353.     Screen.MousePointer = 0
  354. End Sub
  355.  
  356. '----------------------------------------------------------
  357. ' Procedure: CreateProgManItem
  358. '
  359. ' Arguments: X           The form where Label1 exists
  360. '
  361. '            CmdLine$    A string that contains the command
  362. '                        line for the item/icon.
  363. '                        ie 'c:\myapp\setup.exe'
  364. '
  365. '            IconTitle$  A string that contains the item's
  366. '                        caption
  367. '----------------------------------------------------------
  368. Sub CreateProgManItem (x As Form, CmdLine$, IconTitle$)
  369.     
  370.     Screen.MousePointer = 11
  371.     
  372.     '----------------------------------------------------------------------
  373.     ' Windows requires DDE in order to create a program group and item.
  374.     ' Here, a Visual Basic label control is used to generate the DDE messages
  375.     '----------------------------------------------------------------------
  376.     On Error Resume Next
  377.  
  378.  
  379.     '---------------------------------
  380.     ' Set LinkTopic to PROGRAM MANAGER
  381.     '---------------------------------
  382.     x.Label1.LinkTopic = "ProgMan|Progman"
  383.     x.Label1.LinkMode = 2
  384.     For i% = 1 To 10                                         ' Loop to ensure that there is enough time to
  385.       z% = DoEvents()                                        ' process DDE Execute.  This is redundant but needed
  386.     Next                                                     ' for debug windows.
  387.     x.Label1.LinkTimeout = 100
  388.  
  389.     
  390.     '------------------------------------------------
  391.     ' Create Program Item, one of the icons to launch
  392.     ' an application from Program Manager
  393.     '------------------------------------------------
  394.     If gfWin31% Then
  395.     ' Win 3.1 has a ReplaceItem, which will allow us to replace existing icons
  396.     x.Label1.LinkExecute "[ReplaceItem(" + IconTitle$ + ")]"
  397.     End If
  398.     x.Label1.LinkExecute "[AddItem(" + CmdLine$ + Chr$(44) + IconTitle$ + Chr$(44) + ",,)]"
  399.     x.Label1.LinkExecute "[ShowGroup(" + gGroupName + ", 1)]"       ' This will ensure that Program Manager does not
  400.                                     ' have a Maximized group, which causes problem in RestoreProgMan
  401.  
  402.     '-----------------
  403.     ' Reset properties
  404.     '-----------------
  405.     x.Label1.LinkTimeout = 50
  406.     x.Label1.LinkMode = 0
  407.     
  408.     Screen.MousePointer = 0
  409. End Sub
  410.  
  411. '----------------------------------------------------------
  412. ' Check for the existence of a file by attempting an OPEN.
  413. '----------------------------------------------------------
  414. Function FileExists (path$) As Integer
  415.  
  416.     x = FreeFile
  417.  
  418.     On Error Resume Next
  419.     Open path$ For Input As x
  420.     If Err = 0 Then
  421.     FileExists = True
  422.     Else
  423.     FileExists = False
  424.     End If
  425.     Close x
  426.  
  427. End Function
  428.  
  429. '------------------------------------------------
  430. ' Get the disk space free for the current drive
  431. '------------------------------------------------
  432. Function GetDiskSpaceFree (drive As String) As Long
  433.     ChDrive drive
  434.     GetDiskSpaceFree = DiskSpaceFree()
  435. End Function
  436.  
  437. '----------------------------------------------------
  438. ' Get the disk Allocation unit for the current drive
  439. '----------------------------------------------------
  440. Function GetDrivesAllocUnit (drive As String) As Long
  441.     ChDrive drive
  442.     GetDrivesAllocUnit = AllocUnit()
  443. End Function
  444.  
  445. '------------------------
  446. ' Get the size of the file
  447. '------------------------
  448. Function GetFileSize (source$) As Long
  449.     x = FreeFile
  450.     Open source$ For Binary Access Read As x
  451.     GetFileSize = LOF(x)
  452.     Close x
  453. End Function
  454.  
  455. Function GetFileVersion (FileToCheck As String) As String
  456.     On Error Resume Next
  457.     VersionInfoSize& = GetFileVersionInfoSize(FileToCheck, lpdwHandle&)
  458.     If VersionInfoSize& = 0 Then
  459.     GetFileVersion = ""
  460.     Exit Function
  461.     End If
  462.     lpvdata$ = String(VersionInfoSize&, Chr$(0))
  463.     VersionInfo% = GetFileVersionInfo(FileToCheck, lpdwHandle&, VersionInfoSize&, lpvdata$)
  464.     ptrFixed% = VerQueryValue(lpvdata$, "\FILEVERSION", lplpBuffer&, lpcb%)
  465.     If ptrFixed% = 0 Then
  466.     ' Take a shot with the hardcoded TransString
  467.     TransString$ = "040904E4"
  468.     ptrString% = VerQueryValue(lpvdata$, "\StringFileInfo\" & TransString$ & "\CompanyName", lplpBuffer&, lpcb%)
  469.     If ptrString% <> 0 Then GoTo GetValues
  470.     ptrFixed% = VerQueryValue(lpvdata$, "\", lplpBuffer&, lpcb%)
  471.     If ptrFixed% = 0 Then
  472.         GetFileVersion = ""
  473.         Exit Function
  474.     Else
  475.         TransString$ = ""
  476.         fixedstr$ = String(lpcb% + 1, Chr(0))
  477.         stringcopy& = lstrcpyn(fixedstr$, lplpBuffer&, lpcb% + 1)
  478.         For i = lpcb% To 1 Step -1
  479.         char$ = Hex(Asc(Mid(fixedstr$, i, 1)))
  480.         If Len(char$) = 1 Then
  481.             char$ = "0" + char$
  482.         End If
  483.         TransString$ = TransString$ + char$
  484.         If Len(TransString$ & nextchar$) Mod 8 = 0 Then
  485.             TransString$ = "&H" & TransString$
  486.             TransValue& = Val(TransString$)
  487.             TransString$ = ""
  488.         End If
  489.         Next i
  490.     End If
  491.     End If
  492.     TransTable$ = String(lpcb% + 1, Chr(0))
  493.     TransString$ = String(0, Chr(0))
  494.     stringcopy& = lstrcpyn(TransTable$, lplpBuffer&, lpcb% + 1)
  495.     For i = 1 To lpcb%
  496.     char$ = Hex(Asc(Mid(TransTable$, i, 1)))
  497.     If Len(char$) = 1 Then
  498.         char$ = "0" + char$
  499.     End If
  500.     If Len(TransString$ & nextchar$) Mod 4 = 0 Then
  501.         nextchar$ = char$
  502.     Else
  503.         TransString$ = TransString$ + char$ + nextchar$
  504.         nextchar$ = ""
  505.         char$ = ""
  506.     End If
  507.     Next i
  508. GetValues:
  509.     ptrString% = VerQueryValue(lpvdata$, "\StringFileInfo\" & TransString$ & "\FileVersion", lplpBuffer&, lpcb%)
  510.     If ptrString% = 1 Then
  511.     TransTable$ = String(lpcb%, Chr(0))
  512.     stringcopy& = lstrcpyn(TransTable$, lplpBuffer&, lpcb% + 1)
  513.     GetFileVersion = TransTable$
  514.     Else
  515.     GetFileVersion = ""
  516.     End If
  517. End Function
  518.  
  519. '--------------------------------------------------
  520. ' Calls the windows API to get the windows directory
  521. '--------------------------------------------------
  522. Function GetWindowsDir () As String
  523.     temp$ = String$(145, 0)              ' Size Buffer
  524.     x = GetWindowsDirectory(temp$, 145)  ' Make API Call
  525.     temp$ = Left$(temp$, x)              ' Trim Buffer
  526.  
  527.     If Right$(temp$, 1) <> "\" Then      ' Add \ if necessary
  528.     GetWindowsDir$ = temp$ + "\"
  529.     Else
  530.     GetWindowsDir$ = temp$
  531.     End If
  532. End Function
  533.  
  534. '---------------------------------------------------------
  535. ' Calls the windows API to get the windows\SYSTEM directory
  536. '---------------------------------------------------------
  537. Function GetWindowsSysDir () As String
  538.     temp$ = String$(145, 0)                 ' Size Buffer
  539.     x = GetSystemDirectory(temp$, 145)      ' Make API Call
  540.     temp$ = Left$(temp$, x)                 ' Trim Buffer
  541.  
  542.     If Right$(temp$, 1) <> "\" Then         ' Add \ if necessary
  543.     GetWindowsSysDir$ = temp$ + "\"
  544.     Else
  545.     GetWindowsSysDir$ = temp$
  546.     End If
  547. End Function
  548.  
  549. '------------------------------------------------------
  550. ' Function:   IsValidPath as integer
  551. ' arguments:  DestPath$         a string that is a full path
  552. '             DefaultDrive$     the default drive.  eg.  "C:"
  553. '
  554. '  If DestPath$ does not include a drive specification,
  555. '  IsValidPath uses Default Drive
  556. '
  557. '  When IsValidPath is finished, DestPath$ is reformated
  558. '  to the format "X:\dir\dir\dir\"
  559. '
  560. ' Result:  True (-1) if path is valid.
  561. '          False (0) if path is invalid
  562. '-------------------------------------------------------
  563. Function IsValidPath (DestPath$, ByVal DefaultDrive$) As Integer
  564.  
  565.     '----------------------------
  566.     ' Remove left and right spaces
  567.     '----------------------------
  568.     DestPath$ = RTrim$(LTrim$(DestPath$))
  569.     
  570.  
  571.     '-----------------------------
  572.     ' Check Default Drive Parameter
  573.     '-----------------------------
  574.     If Right$(DefaultDrive$, 1) <> ":" Or Len(DefaultDrive$) <> 2 Then
  575.     MsgBox "Bad default drive parameter specified in IsValidPath Function.  You passed,  """ + DefaultDrive$ + """.  Must be one drive letter and "":"".  For example, ""C:"", ""D:""...", 64, "Setup Kit Error"
  576.     GoTo parseErr
  577.     End If
  578.     
  579.  
  580.     '-------------------------------------------------------
  581.     ' Insert default drive if path begins with root backslash
  582.     '-------------------------------------------------------
  583.     If Left$(DestPath$, 1) = "\" Then
  584.     DestPath$ = DefaultDrive + DestPath$
  585.     End If
  586.     
  587.     '-----------------------------
  588.     ' check for invalid characters
  589.     '-----------------------------
  590.     On Error Resume Next
  591.     tmp$ = Dir$(DestPath$)
  592.     If Err <> 0 Then
  593.     GoTo parseErr
  594.     End If
  595.     
  596.  
  597.     '-----------------------------------------
  598.     ' Check for wildcard characters and spaces
  599.     '-----------------------------------------
  600.     If (InStr(DestPath$, "*") <> 0) GoTo parseErr
  601.     If (InStr(DestPath$, "?") <> 0) GoTo parseErr
  602.     If (InStr(DestPath$, " ") <> 0) GoTo parseErr
  603.      
  604.     
  605.     '------------------------------------------
  606.     ' Make Sure colon is in second char position
  607.     '------------------------------------------
  608.     If Mid$(DestPath$, 2, 1) <> Chr$(58) Then GoTo parseErr
  609.     
  610.  
  611.     '-------------------------------
  612.     ' Insert root backslash if needed
  613.     '-------------------------------
  614.     If Len(DestPath$) > 2 Then
  615.       If Right$(Left$(DestPath$, 3), 1) <> "\" Then
  616.     DestPath$ = Left$(DestPath$, 2) + "\" + Right$(DestPath$, Len(DestPath$) - 2)
  617.       End If
  618.     End If
  619.  
  620.     '-------------------------
  621.     ' Check drive to install on
  622.     '-------------------------
  623.     drive$ = Left$(DestPath$, 1)
  624.     ChDrive (drive$)                                                        ' Try to change to the dest drive
  625.     If Err <> 0 Then GoTo parseErr
  626.     
  627.     '-----------
  628.     ' Add final \
  629.     '-----------
  630.     If Right$(DestPath$, 1) <> "\" Then
  631.     DestPath$ = DestPath$ + "\"
  632.     End If
  633.     
  634.  
  635.     '-------------------------------------
  636.     ' Root dir is a valid dir
  637.     '-------------------------------------
  638.     If Len(DestPath$) = 3 Then
  639.     If Right$(DestPath$, 2) = ":\" Then
  640.         GoTo ParseOK
  641.     End If
  642.     End If
  643.     
  644.  
  645.     '------------------------
  646.     ' Check for repeated Slash
  647.     '------------------------
  648.     If InStr(DestPath$, "\\") <> 0 Then GoTo parseErr
  649.     
  650.     '--------------------------------------
  651.     ' Check for illegal directory names
  652.     '--------------------------------------
  653.     legalChar$ = "!#$%&'()-0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`{}~.ⁿΣ÷─╓▄▀"
  654.     BackPos = 3
  655.     forePos = InStr(4, DestPath$, "\")
  656.     Do
  657.     temp$ = Mid$(DestPath$, BackPos + 1, forePos - BackPos - 1)
  658.     
  659.     '----------------------------
  660.     ' Test for illegal characters
  661.     '----------------------------
  662.     For i = 1 To Len(temp$)
  663.         If InStr(legalChar$, UCase$(Mid$(temp$, i, 1))) = 0 Then GoTo parseErr
  664.     Next i
  665.  
  666.     '-------------------------------------------
  667.     ' Check combinations of periods and lengths
  668.     '-------------------------------------------
  669.     periodPos = InStr(temp$, ".")
  670.     length = Len(temp$)
  671.     If periodPos = 0 Then
  672.         If length > 8 Then GoTo parseErr                         ' Base too long
  673.     Else
  674.         If periodPos > 9 Then GoTo parseErr                      ' Base too long
  675.         If length > periodPos + 3 Then GoTo parseErr             ' Extension too long
  676.         If InStr(periodPos + 1, temp$, ".") <> 0 Then GoTo parseErr' Two periods not allowed
  677.     End If
  678.  
  679.     BackPos = forePos
  680.     forePos = InStr(BackPos + 1, DestPath$, "\")
  681.     Loop Until forePos = 0
  682.  
  683. ParseOK:
  684.     IsValidPath = True
  685.     Exit Function
  686.  
  687. parseErr:
  688.     IsValidPath = False
  689. End Function
  690.  
  691. '----------------------------------------------------
  692. ' Prompt for the next disk.  Use the FileToLookFor$
  693. ' argument to verify that the proper disk, disk number
  694. ' wDiskNum, was inserted.
  695. '----------------------------------------------------
  696. Function PromptForNextDisk (wDiskNum As Integer, FileToLookFor$) As Integer
  697.  
  698.     '-------------------------
  699.     ' Test for file
  700.     '-------------------------
  701.     Ready = False
  702.     On Error Resume Next
  703.     temp$ = Dir$(FileToLookFor$)
  704.  
  705.     '------------------------
  706.     ' If not found, start loop
  707.     '------------------------
  708.     If Err <> 0 Or Len(temp$) = 0 Then
  709.     While Not Ready
  710.         Err = 0
  711.         '----------------------------
  712.         ' Put up msg box
  713.         '----------------------------
  714.         Beep
  715.         x = MsgBox("Please insert disk # " + Format$(wDiskNum%), 49, "SETUP")
  716.         If x = 2 Then
  717.         '-------------------------------
  718.         ' Use hit cancel, abort the copy
  719.         '-------------------------------
  720.         PromptForNextDisk = False
  721.         GoTo ExitProc
  722.         Else
  723.         '----------------------------------------
  724.         ' User hits OK, try to find the file again
  725.         '----------------------------------------
  726.         temp$ = Dir$(FileToLookFor$)
  727.         If Err = 0 And Len(temp$) <> 0 Then
  728.             PromptForNextDisk = True
  729.             Ready = True
  730.         End If
  731.         End If
  732.     Wend
  733.     Else
  734.     PromptForNextDisk = True
  735.     End If
  736.  
  737.     
  738.  
  739. ExitProc:
  740.  
  741. End Function
  742.  
  743. Sub RestoreProgMan ()
  744.     On Error GoTo RestoreProgManErr
  745.     AppActivate "Program Manager"   ' Activate Program Manager.
  746.     SendKeys "%{ }{Enter}", True      ' Send Restore keystrokes.
  747. RestoreProgManErr:
  748.     Exit Sub
  749. End Sub
  750.  
  751. '-----------------------------------------------------------------------------
  752. ' Set the Destination File's date and time to the Source file's date and time
  753. '-----------------------------------------------------------------------------
  754. Function SetFileDateTime (SourceFile As String, DestinationFile As String) As Integer
  755.     x = SetTime(SourceFile, DestinationFile)
  756.     SetFileDateTime = -1
  757. End Function
  758.  
  759. Sub UpdateStatus (FileBytes As Long)
  760. '-----------------------------------------------------------------------------
  761. ' Update the status bar using form.control Statusdlg.Picture2
  762. '-----------------------------------------------------------------------------
  763.     Static position
  764.     Dim estTotal As Long
  765.  
  766.     estTotal = Val(Statusdlg.total.Tag)
  767.     If estTotal = False Then
  768.     estTotal = 10000000
  769.     End If
  770.  
  771.     position = position + CSng((FileBytes / estTotal) * 100)
  772.     If position > 100 Then
  773.     position = 100
  774.     End If
  775.     Statusdlg.Picture2.Cls
  776.     Statusdlg.Picture2.Line (0, 0)-((position * (Statusdlg.Picture2.ScaleWidth / 100)), Statusdlg.Picture2.ScaleHeight), QBColor(4), BF
  777.  
  778.     Txt$ = Format$(CLng(position)) + "%"
  779.     Statusdlg.Picture2.CurrentX = (Statusdlg.Picture2.ScaleWidth - Statusdlg.Picture2.TextWidth(Txt$)) \ 2
  780.     Statusdlg.Picture2.CurrentY = (Statusdlg.Picture2.ScaleHeight - Statusdlg.Picture2.TextHeight(Txt$)) \ 2
  781.     Statusdlg.Picture2.Print Txt$
  782.  
  783.     r = BitBlt(Statusdlg.Picture1.hDC, 0, 0, Statusdlg.Picture2.ScaleWidth, Statusdlg.Picture2.ScaleHeight, Statusdlg.Picture2.hDC, 0, 0, SRCCOPY)
  784.  
  785. End Sub
  786.  
  787.